package com.fit.exercise.msgp2p;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextPane;
import javax.swing.border.EmptyBorder;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;

public class GroupChatFrame extends JFrame {
	/**
	 * 
	 */
	private static final long serialVersionUID = -1647463931357400650L;
	private JPanel contentPane;
	private final JTextPane chatContent = new JTextPane();
	private final JSplitPane splitPane = new JSplitPane();
	private final JPanel panel_4 = new JPanel();
	private final JPanel panel_5 = new JPanel();
	private final JSplitPane splitPane_1 = new JSplitPane();
	private final JPanel panel = new JPanel();
	private final JPanel panel_1 = new JPanel();
	private final JTextArea textArea = new JTextArea();
	private final JButton btnSend = new JButton("Send");
	private JPopupMenu popupMenu;

	private DefaultListModel<PersonInfo> listModel = new DefaultListModel<>();

	private JList<PersonInfo> list = new JList<PersonInfo>(getListModel());
	private final JScrollPane scrollPane = new JScrollPane(list);

	private final JPanel panel_3 = new JPanel();
	private final JButton btnAddFriendToGroup = new JButton(
			"Add friend to group");

	// The unique number to identify chatGroup
	private Long chatGroupNumber;

	/**
	 * Create the frame.
	 * 
	 * @param port
	 */

	public GroupChatFrame() {
		initGUI();
	}

	private void initGUI() {
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				close();
			}
		});
		setMinimumSize(new Dimension(700, 450));
		setTitle("Group Chat Dialog");
		setPreferredSize(new Dimension(800, 500));
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		setBounds(100, 100, 450, 300);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(new BorderLayout(0, 0));
		splitPane.setResizeWeight(1.0);

		contentPane.add(splitPane, BorderLayout.CENTER);

		splitPane.setLeftComponent(panel_4);
		panel_4.setLayout(new BorderLayout(0, 0));
		panel_1.setLayout(new BoxLayout(panel_1, BoxLayout.X_AXIS));
		splitPane_1.setResizeWeight(1.0);
		splitPane_1.setOrientation(JSplitPane.VERTICAL_SPLIT);

		panel_4.add(splitPane_1, BorderLayout.CENTER);

		splitPane_1.setLeftComponent(panel);
		panel.setLayout(new BorderLayout(0, 0));
		getChatContent().setEditable(false);
		panel.add(getChatContent());

		panel.add(panel_3, BorderLayout.SOUTH);
		panel_3.setLayout(new BoxLayout(panel_3, BoxLayout.X_AXIS));
		btnAddFriendToGroup.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {

				final FriendsList_DlgAdd friendsList_DlgAdd = new FriendsList_DlgAdd() {

					@Override
					protected void sendData(JTable table) {
						int[] rowIds = table.getSelectedRows();
						if (rowIds.length <= 0) {
							JOptionPane.showMessageDialog(table,
									"Please select one friend at least");
						} else {
							try {
								List<PersonInfo> invitedList = new ArrayList<PersonInfo>();

								for (int i = 0; i < getThis().listModel.size(); i++) {
									invitedList.add(getThis().listModel.get(i));
								}

								invitedList.add(T2Messenger.myInfo);

								for (int i : rowIds) {
									if (!invitedList
											.contains(T2Messenger.friendList
													.get(i)))
										invitedList.add(T2Messenger.friendList
												.get(i));
								}

								if (invitedList.size() > getThis().listModel
										.size() + 1) {

									for (int j = getThis().listModel.size() + 1; j < invitedList
											.size(); j++) {
										UDPUtil.sendMessage(
												Util.convertToByteArray(invitedList),
												invitedList.get(j),
												Packet.TYPE_GROUP_CHAT_ADD_MORE,
												Packet.FLAG_DATA,
												ByteBuffer
														.allocate(
																Packet.OPTION_DATA_LENGTH)
														.putLong(
																getThis()
																		.getChatGroupNumber())
														.array());

									}

								} else {
									JOptionPane
											.showMessageDialog(getThis(),
													"All friends you selected was in chat group");
								}
							} catch (IOException e) {
								e.printStackTrace();
							}
						}
					}
				};
				friendsList_DlgAdd.setVisible(true);
			}

		});

		panel_3.add(btnAddFriendToGroup);

		splitPane_1.setRightComponent(panel_1);

		panel_1.add(textArea);
		btnSend.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				sendMessage();
			}
		});
		btnSend.setMaximumSize(new Dimension(70, 50));
		btnSend.setMargin(new Insets(2, 2, 2, 2));
		btnSend.setSize(new Dimension(70, 50));
		btnSend.setPreferredSize(new Dimension(70, 50));

		panel_1.add(btnSend);
		panel_5.setMinimumSize(new Dimension(150, 10));
		panel_5.setPreferredSize(new Dimension(150, 10));

		splitPane.setRightComponent(panel_5);
		panel_5.setLayout(new BorderLayout(0, 0));
		panel_5.add(scrollPane, BorderLayout.CENTER);

		popupMenu = new JPopupMenu();
		JMenuItem editItem = new JMenuItem("Add friend");
		popupMenu.add(editItem);
		editItem.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				PersonInfo personInfo = list.getSelectedValue();

				if (personInfo != null) {
					if (!T2Messenger.friendList.contains(personInfo)) {
						JOptionPane.showMessageDialog(null,
								"This friend is exist");
					} else {
						T2Messenger.friendList.add(personInfo);
						T2Messenger.listModel.addElement(personInfo.getName()
								+ " - (" + personInfo.getIpAddress() + ":"
								+ personInfo.getPort() + ")");
						try {
							Util.saveToFile(Util.filePath, personInfo);
						} catch (IOException e) {
							e.printStackTrace();
						}
						JOptionPane.showMessageDialog(null,
								"Add friend successfully");
					}
				}
			}
		});

		list.addMouseListener(new MouseAdapter() {

			@Override
			public void mousePressed(MouseEvent e) {
				check(e);
			}

			@Override
			public void mouseReleased(MouseEvent e) {
				check(e);
			}

			private void check(MouseEvent e) {
				if (e.isPopupTrigger()) {
					// select item
					list.setSelectedIndex(list.locationToIndex(e.getPoint()));
					// show popup
					popupMenu.show(list, e.getX(), e.getY());
				}
			}
		});
	}

	private void sendMessage() {
		try {
			for (int i = 0; i < listModel.size(); i++) {
				UDPUtil.sendMessage(
						textArea.getText(),
						listModel.get(i),
						Packet.TYPE_GROUP_CHAT_MSG,
						Packet.FLAG_DATA,
						ByteBuffer.allocate(Packet.OPTION_DATA_LENGTH)
								.putLong(chatGroupNumber).array());
			}
			StyledDocument doc = chatContent.getStyledDocument();
			SimpleAttributeSet receiverKeyword = new SimpleAttributeSet();
			StyleConstants.setBold(receiverKeyword, true);
			StyleConstants.setForeground(receiverKeyword, Color.ORANGE);
			doc.insertString(doc.getLength(), "Me: ", receiverKeyword);
			doc.insertString(doc.getLength(), textArea.getText() + "\n", null);
		} catch (Exception e) {
			e.printStackTrace();
			JOptionPane.showMessageDialog(btnSend, "Can not send message");
		}
	}

	public void addElementToListModel(PersonInfo e) {
		getListModel().addElement(e);
	}

	public JTextPane getChatContent() {
		return chatContent;
	}

	public Long getChatGroupNumber() {
		return chatGroupNumber;
	}

	public void setChatGroupNumber(Long chatGroupNumber) {
		this.chatGroupNumber = chatGroupNumber;
	}

	public DefaultListModel<PersonInfo> getListModel() {
		return listModel;
	}

	public void setListModel(DefaultListModel<PersonInfo> listModel) {
		this.listModel = listModel;
	}

	private GroupChatFrame getThis() {
		return this;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;

		if (!(obj instanceof GroupChatFrame))
			return false;

		GroupChatFrame temp = (GroupChatFrame) obj;
		return temp.getChatGroupNumber().compareTo(this.getChatGroupNumber()) == 0;
	}

	public void close() {
		this.dispose();
		T2Messenger.groupChatFrames.remove(this);
	}
}
